﻿using Spectre.Console;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace WorkTool.Helpers
{
    public static class ConsoleTablePrinter
    {
        public static void PrintEnhancedTable<T>(List<T> data, bool showHeaders = true) where T : class, new()
        {
            if (data == null || data.Count == 0)
            {
                AnsiConsole.MarkupLine("[yellow]--------------------没有可显示的数据--------------------[/]");
                return;
            }

            var table = new Table
            {
                Border = TableBorder.Rounded,
                BorderStyle = new Style(Color.DarkCyan),
                ShowHeaders = showHeaders,
            };
            var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            // 添加表头
            foreach (var property in properties)
            {
                var descriptionAttr = property.GetCustomAttribute<DescriptionAttribute>();
                table.AddColumn(new TableColumn($"[bold mediumpurple2]{descriptionAttr?.Description ?? property.Name}[/]")
                    // .Width(columnWidths[key])
                    .LeftAligned());
            }
            // 添加数据行（带交替行颜色）
            for (int i = 0; i < data.Count; i++)
            {
                var values = properties.Select(p =>
                {
                    var value = p.GetValue(data[i]) == null ? "[grey]N/A[/]" : p.GetValue(data[i]).ToString();
                    return i % 2 == 0 ? $"[yellow]{value}[/]" : $"[aqua]{value}[/]";
                }).ToArray();
                table.AddRow(values.ToArray());
            }
            AnsiConsole.Write(table);
        }

        public static void PrintEnhancedTableByDictionary(List<Dictionary<string, string>> data, bool showHeaders = true)
        {
            if (data == null || data.Count == 0)
            {
                AnsiConsole.MarkupLine("[yellow]--------------------没有可显示的数据--------------------[/]");
                return;
            }

            var table = new Table
            {
                Border = TableBorder.Rounded,
                BorderStyle = new Style(Color.DarkCyan),
                ShowHeaders = showHeaders,
            };

            // 动态确定列宽
            var columnWidths = new Dictionary<string, int>();
            foreach (var key in data[0].Keys)
            {
                int maxWidth = key.Length;
                foreach (var row in data)
                {
                    if (row.TryGetValue(key, out var value))
                    {
                        maxWidth = Math.Max(maxWidth, value?.Length ?? 0);
                    }
                }
                columnWidths[key] = Math.Min(Math.Max(maxWidth, 10), 80); // 限制在10-50字符
            }

            // 添加列
            foreach (var key in data[0].Keys)
            {
                table.AddColumn(new TableColumn($"[bold mediumpurple2]{key}[/]")
                    .Width(columnWidths[key])
                    .LeftAligned());
            }

            // 添加数据行（带交替行颜色）
            for (int i = 0; i < data.Count; i++)
            {
                var row = data[i];
                var values = new List<string>();
                foreach (var key in data[0].Keys)
                {
                    var value = row.TryGetValue(key, out var val) ? val : "[grey]N/A[/]";
                    values.Add(i % 2 == 0 ? $"[yellow]{value}[/]" : $"[aqua]{value}[/]");
                }
                table.AddRow(values.ToArray());
            }

            AnsiConsole.Write(table);
        }

        public static void PrintTable(List<Dictionary<string, string>> data)
        {
            if (data == null || data.Count == 0)
            {
                Console.WriteLine("--------------------没有可显示的数据--------------------");
                return;
            }

            // 获取所有列名
            var columnNames = data[0].Keys.ToList();

            // 计算每列的最大宽度（考虑中文字符）
            var columnWidths = new Dictionary<string, int>();
            foreach (var column in columnNames)
            {
                // 列名本身的宽度（考虑中文）
                int maxWidth = GetStringWidth(column);

                // 查找该列所有值中的最大宽度
                foreach (var row in data)
                {
                    if (row.TryGetValue(column, out var value))
                    {
                        string valueStr = value ?? "null";
                        int width = GetStringWidth(valueStr);
                        if (width > maxWidth)
                        {
                            maxWidth = width;
                        }
                    }
                }
                // 设置最小列宽为18，最大不超过50（以英文字符计）
                columnWidths[column] = Math.Clamp(maxWidth, 10, 50);
            }

            // 打印表头
            PrintDivider(columnNames, columnWidths);
            PrintRow(columnNames, columnWidths, true); // 表头居中
            PrintDivider(columnNames, columnWidths);

            // 打印数据行
            foreach (var row in data)
            {
                var rowValues = columnNames.Select(col =>
                    row.TryGetValue(col, out var value) ? value?.ToString() ?? "null" : "N/A").ToList();
                PrintRow(rowValues, columnWidths);
            }

            PrintDivider(columnNames, columnWidths);
        }

        // 获取字符串的显示宽度（中文算2个字符，英文算1个）
        private static int GetStringWidth(string s)
        {
            if (string.IsNullOrEmpty(s)) return 0;

            int width = 0;
            foreach (char c in s)
            {
                width += IsChinese(c) ? 2 : 1;
            }
            return width;
        }

        // 判断字符是否为中文
        private static bool IsChinese(char c)
        {
            return c >= 0x4E00 && c <= 0x9FFF;
        }

        private static void PrintRow(List<string> values, Dictionary<string, int> columnWidths, bool isHeader = false)
        {
            var columnNames = columnWidths.Keys.ToList();
            StringBuilder row = new StringBuilder("|");

            for (int i = 0; i < values.Count; i++)
            {
                string value = values[i];
                string columnName = columnNames[i];
                int width = columnWidths[columnName];
                int valueWidth = GetStringWidth(value);

                // 处理超长文本
                if (valueWidth > width)
                {
                    value = TruncateString(value, width - 3);
                    valueWidth = GetStringWidth(value) + 3; // 加上...的宽度
                }

                // 计算左右空格
                int totalSpaces = width - valueWidth;
                int leftSpaces;
                int rightSpaces;
                if (totalSpaces > 0)
                {
                    leftSpaces = isHeader ? totalSpaces / 2 : 1; // 表头居中，数据左对齐
                    rightSpaces = totalSpaces - leftSpaces + 2 < 0 ? 0 : totalSpaces - leftSpaces + 2; // 多补两个空格
                }
                else
                {
                    leftSpaces = 1; // 多补一个空格
                    rightSpaces = 1; // 多补一个空格
                }
                string formattedValue =
                    new string(' ', leftSpaces) +
                    value +
                    new string(' ', rightSpaces);

                row.Append(formattedValue).Append("|");
            }

            Console.WriteLine(row.ToString());
        }

        // 截断字符串并考虑中文字符
        private static string TruncateString(string s, int maxWidth)
        {
            int currentWidth = 0;
            StringBuilder result = new StringBuilder();

            foreach (char c in s)
            {
                int charWidth = IsChinese(c) ? 2 : 1;
                if (currentWidth + charWidth > maxWidth)
                {
                    break;
                }
                result.Append(c);
                currentWidth += charWidth;
            }

            return result.ToString();
        }

        private static void PrintDivider(List<string> columnNames, Dictionary<string, int> columnWidths)
        {
            StringBuilder divider = new StringBuilder("+");
            foreach (var column in columnNames)
            {
                // 每个单元格宽度 = 内容宽度 + 左右各1个空格
                divider.Append(new string('-', columnWidths[column] + 2)).Append("+");
            }
            Console.WriteLine(divider.ToString());
        }
    }
}